package com.sunwhite.codeidea.reflect.demo1.step040.entity;

import javassist.*;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;

/**
 * 实体助手工厂
 */
public final class EntityHelperFactory {
    /**
     * 私有化类默认构造器
     */
    private EntityHelperFactory() {
    }

    /**
     * 助手字典类，用来存放助手类
     */
    private static final Map<Class<?>,AbstractEntityHelper> entiyHelperFactory=new HashMap<>();
    /**
     * 获取帮助
     *
     * @param entityClazz 实体类
     * @return
     */
    public static AbstractEntityHelper getEntityHelper(Class<?> entityClazz) throws Exception {
        // 这里需要全新设计,
        // 接下来就该请出 javassist 了!
//        判断是否为空
        if(null==entityClazz){
            return null;
        }
        AbstractEntityHelper entityHelper=entiyHelperFactory.get(entityClazz);
        if (null!=entityHelper){
            return entityHelper;
        }
        //使用javassist生成entityHelper
        //获取类池
        ClassPool classPool = ClassPool.getDefault();
        ClassPath classPath = classPool.appendSystemPath();
        //导入相关类，生成entityHelper的代码
        classPool.importPackage(ResultSet.class.getName());
        classPool.importPackage(entityClazz.getName());
        //抽象助手类
        CtClass abstractEntityHelperClazz = classPool.getCtClass(AbstractEntityHelper.class.getName());
        //助手实现类的名称
        String entityHelperClazzName = entityClazz.getName() + "_Helper";
        //创建助手类，会生成以下代码
        CtClass entityHelperClazz = classPool.makeClass(entityHelperClazzName, abstractEntityHelperClazz);
        //创建默认的构造器
        CtConstructor ctConstructor = new CtConstructor(new CtClass[0], entityHelperClazz);
       //创建默认构造器的方法体
        ctConstructor.setBody("{}");
        entityHelperClazz.addConstructor(ctConstructor);
        //用户创建方法字符串
        StringBuffer sb = new StringBuffer();
        sb.append("public Object create(java.sql.ResultSet rs) throws Exception{\n");
        sb.append(entityClazz.getName()).append(" obj =new ").append(entityClazz.getName()).append("();\n");
        //通过反射的方式获取实体类的字段数组并拼接成字符串放入需要创建的类中
        Field[] declaredFields = entityClazz.getDeclaredFields();
        for (Field field : declaredFields) {
            Column column = field.getAnnotation(Column.class);
            if (column==null){
                continue;
            }
            String columnName = column.name();
            if (field.getType() == Integer.TYPE) {
                // 生成如下代码 :
                // obj._userId = rs.getInt("user_id");
                sb.append("obj.")
                        .append(field.getName())
                        .append(" = rs.getInt(\"")
                        .append(columnName)
                        .append("\");\n");
            } else if (field.getType().equals(String.class)) {
                // 生成如下代码 :
                // obj._userName = rs.getString("user_name");
                sb.append("obj.")
                        .append(field.getName())
                        .append(" = rs.getString(\"")
                        .append(columnName)
                        .append("\");\n");
            } else {
                // 不支持的类型...
            }

        }
        sb.append("return obj;\n");
        sb.append("}");
        //创建解析方法
        CtMethod ctMethod = CtNewMethod.make(sb.toString(), entityHelperClazz);
        entityHelperClazz.addMethod(ctMethod);
        Class<?> javaClazz = entityHelperClazz.toClass();
        //创建对象帮助实例
        AbstractEntityHelper abstractEntityHelper = (AbstractEntityHelper) javaClazz.newInstance();
        entiyHelperFactory.put(entityClazz,abstractEntityHelper);
        return abstractEntityHelper;
    }
}
